home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-ARM / PROC-ARM.{21 / MM-INIT.H < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-17  |  3.8 KB  |  165 lines

  1. /*
  2.  * linux/include/asm-arm/proc-armv/mm-init.h
  3.  *
  4.  * Copyright (C) 1996 Russell King
  5.  *
  6.  * This contains the code to setup the memory map on an ARM v3 or v4 machine.
  7.  * This is both processor & architecture specific, and requires some
  8.  * more work to get it to fit into our separate processor and architecture
  9.  * structure.
  10.  */
  11.  
  12. /*
  13.  * On ebsa, we want the memory map set up so:
  14.  *
  15.  *   PHYS      VIRT
  16.  * 00000000    00000000    Zero page
  17.  * 000003ff    000003ff    Zero page end
  18.  * 00000000    c0000000    Kernel and all physical memory
  19.  * 01ffffff    c1ffffff    End of physical (32MB)
  20.  * e0000000    e0000000    IO start
  21.  * ffffffff    ffffffff    IO end
  22.  *
  23.  * On rpc, we want:
  24.  *
  25.  *   PHYS      VIRT
  26.  * 10000000    00000000    Zero page
  27.  * 100003ff    000003ff    Zero page end
  28.  * 10000000    c0000000    Kernel and all physical memory
  29.  * 1fffffff    cfffffff    End of physical (32MB)
  30.  * 02000000    d?000000    Screen memory (first image)
  31.  * 02000000    d8000000    Screen memory (second image)
  32.  * 00000000    df000000    StrongARM cache invalidation area
  33.  * 03000000    e0000000    IO start
  34.  * 03ffffff    e0ffffff    IO end
  35.  *
  36.  * We set it up using the section page table entries.
  37.  */
  38. #include <asm/pgtable.h>
  39.  
  40. #define PTE_SIZE (PTRS_PER_PTE * 4)
  41.  
  42. extern unsigned long setup_io_pagetables(unsigned long start_mem);
  43.  
  44. /*
  45.  * Add a SECTION mapping between VIRT and PHYS in domain DOMAIN with protection PROT
  46.  */
  47. static inline void
  48. alloc_init_section(unsigned long *mem, unsigned long virt, unsigned long phys, int domain, int prot)
  49. {
  50.     pgd_t *pgdp;
  51.     pmd_t *pmdp, pmd;
  52.  
  53.     pgdp = pgd_offset_k(virt);
  54.     pmdp = pmd_offset(pgdp, virt);
  55.  
  56.     pmd_val(pmd) = phys | PMD_TYPE_SECT | PMD_DOMAIN(domain) | prot;
  57.     set_pmd(pmdp, pmd);
  58. }
  59.  
  60. /*
  61.  * Clear any mapping
  62.  */
  63. static inline void
  64. free_init_section(unsigned long virt)
  65. {
  66.     pgd_t *pgdp;
  67.     pmd_t *pmdp;
  68.  
  69.     pgdp = pgd_offset_k(virt);
  70.     pmdp = pmd_offset(pgdp, virt);
  71.  
  72.     pmd_clear(pmdp);
  73. }
  74.  
  75. /*
  76.  * Add a PAGE mapping between VIRT and PHYS in domain DOMAIN with protection PROT
  77.  */
  78. static inline void
  79. alloc_init_page(unsigned long *mem, unsigned long virt, unsigned long phys, int domain, int prot)
  80. {
  81.     pgd_t *pgdp;
  82.     pmd_t *pmdp, pmd;
  83.     pte_t *ptep;
  84.  
  85.     pgdp = pgd_offset_k(virt);
  86.     pmdp = pmd_offset(pgdp, virt);
  87.  
  88.     if (pmd_none(*pmdp)) {
  89.         unsigned long memory = *mem;
  90.  
  91.         memory = (memory + PTE_SIZE - 1) & ~(PTE_SIZE - 1);
  92.  
  93.         ptep = (pte_t *)memory;
  94.         memzero(ptep, PTE_SIZE);
  95.  
  96.         pmd_val(pmd) = __virt_to_phys(memory) | PMD_TYPE_TABLE | PMD_DOMAIN(domain);
  97.         set_pmd(pmdp, pmd);
  98.  
  99.         *mem = memory + PTE_SIZE;
  100.     }
  101.  
  102.     ptep = pte_offset(pmdp, virt);
  103.  
  104.     pte_val(*ptep) = phys | prot | PTE_TYPE_SMALL;
  105. }
  106.  
  107. static inline unsigned long
  108. setup_pagetables(unsigned long start_mem, unsigned long end_mem)
  109. {
  110.     unsigned long address;
  111.  
  112.     /*
  113.      * map in zero page
  114.      */
  115.     alloc_init_page(&start_mem, 0, __virt_to_phys(PAGE_OFFSET), DOMAIN_USER, PTE_CACHEABLE);
  116.  
  117.     /*
  118.      * ensure no mappings in user space
  119.      */
  120.     for (address = PGDIR_SIZE; address < PAGE_OFFSET; address += PGDIR_SIZE)
  121.         free_init_section(address);
  122.  
  123.     /*
  124.      * map in physical ram & kernel
  125.      */
  126.     for (address = PAGE_OFFSET; address < end_mem; address += PGDIR_SIZE)
  127.         alloc_init_section(&start_mem, address, __virt_to_phys(address), DOMAIN_KERNEL,
  128.                    PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE | PMD_SECT_AP_WRITE);
  129.  
  130.     /*
  131.      * unmap everything else
  132.      */
  133.     for (address = end_mem; address; address += PGDIR_SIZE)
  134.         free_init_section(address);
  135.  
  136.     /*
  137.      * An area to invalidate the cache
  138.      */
  139.     alloc_init_section(&start_mem, FLUSH_BASE, FLUSH_BASE_PHYS, DOMAIN_KERNEL,
  140.                PMD_SECT_CACHEABLE | PMD_SECT_AP_READ);
  141.  
  142.     /*
  143.      * Now set up our IO mappings
  144.      */
  145.     start_mem = setup_io_pagetables(start_mem);
  146.  
  147.     flush_cache_all();
  148.  
  149.     return start_mem;
  150. }
  151.  
  152. static inline
  153. void mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem)
  154. {
  155.     unsigned long smem;
  156.  
  157.     *start_mem = smem = PAGE_ALIGN(*start_mem);
  158.  
  159.     while (smem < end_mem) {
  160.             clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
  161.             smem += PAGE_SIZE;
  162.     }
  163. }    
  164.  
  165.